home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / eulisp / feel-075.lha / feel0.75 / Src / copyalloc.c < prev    next >
C/C++ Source or Header  |  1992-07-07  |  20KB  |  867 lines

  1.  /*    
  2.   * Allocation routines for feel
  3.   *
  4.   */
  5.  
  6. /* what we need to stay ahead*/
  7. #include "defs.h"
  8. #include "structs.h"
  9. #include "funcalls.h"
  10. #include "global.h"
  11. #include "allocate.h" 
  12. #include "error.h"
  13. #include "table.h"
  14.  
  15. /* other junk */
  16. #include "copy.h"
  17.  
  18. #ifndef DEFAULT_HEAP_SIZE
  19. #define DEFAULT_HEAP_SIZE (4*1024*1024)
  20. #endif
  21.  
  22. #ifndef DEFAULT_STACK_SPACE_SIZE
  23. #define DEFAULT_STACK_SPACE_SIZE (1*1024*1024)
  24. #endif
  25.  
  26. #define N_SLOTS_IN_CLASS N_SLOTS_IN_STRUCT(struct class_structure)
  27. #define N_SLOTS_IN_THREAD N_SLOTS_IN_STRUCT(struct thread_structure)
  28.  
  29. #define ROUNDTO 8
  30. #define ROUND_ADDR(x) ((((int)x)&(ROUNDTO-1))==0 ? x : x+(ROUNDTO-((int)x&(ROUNDTO-1))))
  31.  
  32. #ifdef NODEBUG
  33. #define FPRINTF_GC_BUG(x) 
  34. #define GC_BUG(x)
  35. #else
  36. #define GC_BUG(x) x
  37. #define FPRINTF_GC_BUG(x) fprintf x
  38. #endif
  39.  
  40. LispObject static_ints;
  41.  
  42. void runtime_initialise_allocator(LispObject *stacktop)
  43. {
  44.   static void initialise_stack_space(int);
  45.   extern void init_allocator(int);
  46.   extern int command_line_heap_size;
  47.   extern int command_line_stack_space_size;
  48.   extern int command_line_cons_percentage;
  49.   extern int command_line_cons_cut_off;
  50.  
  51.   int heap,stack_space;
  52.   
  53.   heap = (command_line_heap_size == 0
  54.             ? DEFAULT_HEAP_SIZE 
  55.             : command_line_heap_size);
  56.  
  57.   if (heap < 50)
  58.     heap=heap*1024*1024;
  59.  
  60.  
  61.   {
  62.     extern int command_line_cons_percentage;
  63.     extern int command_line_cons_cut_off;
  64.     
  65.     if (command_line_stack_space_size < 50)
  66.       command_line_stack_space_size = command_line_stack_space_size*1024*1024;
  67.  
  68.     stack_space = (command_line_stack_space_size == 0
  69.            ? DEFAULT_STACK_SPACE_SIZE
  70.            : command_line_stack_space_size);
  71.   }
  72.  
  73.   init_allocator(heap); /* ifdef CGC this does nothing */
  74.   initialise_stack_space(stack_space); /* and this calls gc_init() */
  75.  
  76.   /* so if CGC is defined, all the above does is call gc_init() */
  77.  
  78.   /* Really need a smarter way of doing these... --- like do them last */
  79.   add_root((LispObject *) &state_dynamic_env);
  80.   add_root(&state_last_continue);
  81.   add_root(&state_handler_stack);
  82.   add_root(&state_current_thread);
  83.   allocate_static_integers(stacktop); /* calls gc_malloc*/
  84. }
  85.  
  86. char *allocate_space(LispObject *stacktop,int n)
  87. {
  88.   char* allocate_stack(LispObject *stacktop, int nbytes);  
  89.  
  90.   return allocate_stack(stacktop,n);
  91. }
  92.  
  93. void deallocate_space(LispObject*stacktop,char *addr,int siz)
  94. {
  95.   void deallocate_stack(LispObject *, char *, int);
  96.  
  97.   deallocate_stack(stacktop,addr,siz);
  98. }
  99. void runtime_initialise_collector(LispObject *stacktop)
  100. {
  101.  
  102. }
  103.  
  104. #define NOT_YET_DONE(name) \
  105. { fprintf(stderr,"%s: cannot alloc\n",name) ; return nil;}
  106.   
  107. LispObject Fn_cons(LispObject *stacktop)
  108. {
  109.   LispObject ans;
  110.  
  111.   ans = allocate_nbytes(stacktop+2,sizeof(struct cons_structure),TYPE_CONS); 
  112.   
  113.   lval_classof(ans)=Cons;
  114.   ans->CONS.car= *stacktop;
  115.   ans->CONS.cdr= *(stacktop+1);
  116.   
  117.   return ans;
  118. }
  119.  
  120. /* Optimised to allow easier code in a lot of places... */
  121. LispObject allocate_n_conses(LispObject *stacktop, int n)
  122. {    
  123.   LispObject xx;
  124.   int i;
  125. #ifdef NOWAY  
  126.   struct cons_structure *ptr;
  127.  
  128.   xx=allocate_cbytes(stacktop,n,sizeof(struct cons_structure),TYPE_CONS);
  129.   ptr= &(xx->CONS);
  130.   lval_classof(xx)=Cons;
  131.   ptr++;
  132.   for (i=1; i<n; i++)
  133.     {
  134.       ptr->header.class=Cons; /* XXX */
  135.       ptr->car=nil;    
  136.       (ptr[-1]).cdr=(LispObject)ptr;
  137.       ptr++;
  138.     }
  139.   
  140.   ptr[-1].cdr=nil;
  141.   return xx;
  142. #else
  143.   xx=nil;
  144.   for (i=0; i<n; i++)
  145.     {
  146.       xx=EUCALL_2(Fn_cons,nil,xx);
  147.     }
  148.       
  149.   return xx;
  150.  
  151. #endif
  152. }
  153.  
  154. LispObject allocate_n_envs(LispObject *stacktop, int n)
  155. {    
  156.   LispObject xx;
  157.   int i;
  158.   xx=0;
  159.   for (i=0; i< n; i++)
  160.     {
  161.       xx=allocate_env(stacktop,nil,nil,xx);
  162.     }
  163.  
  164.   return xx;
  165. }
  166.  
  167. LispObject allocate_class(LispObject *stacktop,LispObject class)
  168. {
  169.   LispObject ans;
  170.   int i;
  171.  
  172.   STACK_TMP(class);
  173.   if (class==NULL)
  174.     ans = allocate_nbytes(stacktop,sizeof(struct class_structure),TYPE_CLASS);
  175.   else 
  176.     ans = allocate_nbytes(stacktop,
  177.               sizeof(Object_t)+sizeof(LispObject)*class->CLASS.local_count,
  178.               TYPE_CLASS);
  179.   UNSTACK_TMP(class);
  180.   lval_classof(ans) = class;
  181.  
  182.   (ans->CLASS).name = unbound;
  183.   (ans->CLASS).superclasses = nil;
  184.   (ans->CLASS).subclasses = nil;
  185.   (ans->CLASS).slot_table = nil;
  186.   (ans->CLASS).slot_list = nil;
  187.   (ans->CLASS).direct_slot_list = nil;
  188.   (ans->CLASS).precedence = nil;
  189.   (ans->CLASS).local_count = 0;
  190.   
  191.   if (class!=NULL)
  192.     {
  193.       for (i=N_SLOTS_IN_CLASS ; i<class->CLASS.local_count ; i++)
  194.     slotref(ans,i) = nil;
  195.     }
  196.   return ans;
  197. }
  198.  
  199. LispObject allocate_instance(LispObject *stacktop,LispObject class)
  200. {
  201.   LispObject ans;
  202.   int i;
  203.  
  204.   STACK_TMP(class);
  205.  
  206.   ans=allocate_nbytes(stacktop,sizeof(Object_t)
  207.               +sizeof(LispObject)*class->CLASS.local_count,TYPE_INSTANCE);
  208.   UNSTACK_TMP(class);
  209.   lval_classof(ans)=class;
  210.  
  211.   for (i=0; i<class->CLASS.local_count; i++)
  212.     slotref(ans,i)=nil;
  213.  
  214.   return ans;
  215. }
  216.  
  217. LispObject allocate_thread(LispObject *stacktop,int stack_size, 
  218.                int gc_stack_size, int nslots)
  219.   char* allocate_stack(LispObject *stacktop, int nbytes);
  220.   /* xxx: need extra slots hack */
  221.   LispObject ans,cont;
  222.   int extra;
  223.  
  224.   extra=nslots>0? nslots-N_SLOTS_IN_THREAD: 0;
  225.   cont=allocate_continue(stacktop);
  226.   *stacktop=cont;
  227.   
  228.   
  229.   ans=allocate_nbytes(stacktop+1,
  230.               sizeof(struct thread_structure)+extra*sizeof(LispObject),
  231.               TYPE_THREAD);
  232.   cont = *stacktop;
  233.   *stacktop=ans;
  234.   lval_classof(ans) = Thread;
  235.  
  236.   (ans->THREAD).stack_size = stack_size;
  237.   (ans->THREAD).gc_stack_size = gc_stack_size;
  238.  
  239.   (ans->THREAD).fun = nil;
  240.   (ans->THREAD).args = nil;
  241.   (ans->THREAD).value = nil;
  242.  
  243.   (ans->THREAD).status = 0;
  244.  
  245.   (ans->THREAD).parent = nil;
  246.   (ans->THREAD).cochain = nil;
  247.   
  248.   (ans->THREAD).state = cont;
  249.   (ans->THREAD).stack_base = NULL;
  250.   (ans->THREAD).gc_stack_base = NULL;
  251.  
  252.   ans->THREAD.state->CONTINUE.thread=ans;
  253.  
  254. #ifdef MACHINE_ANY
  255.  
  256.   (ans->THREAD).stack_base = (int *) allocate_stack(stacktop+1,stack_size);
  257.   (ans->THREAD.state)->CONTINUE.gc_stack_pointer =
  258.     (ans->THREAD).gc_stack_base =
  259.       (LispObject *) allocate_stack(stacktop+1,gc_stack_size*sizeof(LispObject));
  260.   
  261.   fprintf(stderr,"{New stack: 0x%x->0x%x}", (ans->THREAD).gc_stack_base,
  262.        (ans->THREAD).gc_stack_base+gc_stack_size);
  263.   STACK_TMP(ans);
  264.   cont=EUCALL_2(Fn_cons,function_default_handler,nil);
  265.   UNSTACK_TMP(ans);
  266.   ans->THREAD.state->CONTINUE.handler_stack = cont;
  267.     
  268. #else
  269.  
  270.   ans->THREAD.stack_base = NULL;
  271.   ans->THREAD.gc_stack_base = NULL;
  272.   ans->THREAD.state->CONTINUE.gc_stack_pointer = NULL;
  273.   ans->THREAD.state->CONTINUE.handler_stack =
  274.        EUCALL_2(Fn_cons,function_default_handler,nil);
  275.  
  276. #endif
  277.   { /* ugh */
  278.     int i;
  279.     if (extra>0)
  280.       for(i=N_SLOTS_IN_THREAD; i<nslots; i++)
  281.     slotref(ans,i) = unbound;
  282.   }
  283.   return ans;
  284. }
  285.  
  286. LispObject allocate_vector(LispObject *stacktop,int size)
  287. {
  288.   LispObject ans;
  289.   int i;
  290.  
  291.   ans = allocate_nbytes(stacktop,sizeof(Object_t)+sizeof(int)+size*sizeof(LispObject),
  292.             TYPE_VECTOR);
  293.   
  294.   lval_classof(ans)= Vector;
  295.   
  296.   ans->VECTOR.length=size;
  297.  
  298.   for(i=0; i<size ; i++)
  299.     vref(ans,i)=nil;
  300.  
  301.   return ans;
  302. }
  303.  
  304. LispObject allocate_string(LispObject *stacktop, char *string, int len)
  305. {
  306.   LispObject ans;
  307.  
  308.   len++;
  309.   len=ROUND_ADDR(len);
  310.   ans = allocate_nbytes(stacktop,sizeof(Object_t)+sizeof(int)+len,
  311.             TYPE_STRING); 
  312.   
  313.   lval_classof(ans)=String;
  314.   ans->STRING.length= len;
  315.   stringof(ans)[len-1]=0;
  316.   strncpy(stringof(ans),string,len);
  317.  
  318.   return ans;
  319. }
  320.  
  321. LispObject allocate_symbol(LispObject *stacktop, char *str)
  322. {
  323.   int hash(char *); /* from tables.c */
  324.  
  325.   LispObject ans;
  326.   LispObject tmp;
  327.   
  328.   tmp=allocate_string(stacktop,str,strlen(str));
  329.   STACK_TMP(tmp);
  330.   ans=allocate_nbytes(stacktop,sizeof(struct symbol_structure),TYPE_SYMBOL);
  331.   UNSTACK_TMP(tmp);
  332.   
  333.   lval_classof(ans)=Symbol;
  334.   (ans->SYMBOL).lvalue = nil;
  335.   (ans->SYMBOL).lmodule = nil;
  336.   (ans->SYMBOL).gvalue = NULL;
  337.   (ans->SYMBOL).left = NULL;
  338.   (ans->SYMBOL).right = NULL;
  339.   (ans->SYMBOL).plist = nil;
  340.   (ans->SYMBOL).hash = hash(str);
  341.   ans->SYMBOL.pname= tmp;
  342.  
  343.   return ans;
  344. }
  345.  
  346. LispObject allocate_table(LispObject *stacktop, LispObject (*comp)(LispObject*))
  347. {
  348.   LispObject ans;
  349.  
  350.   ans=allocate_nbytes(stacktop,sizeof(struct table_structure),TYPE_TABLE);
  351.   
  352.   lval_classof(ans)=Table;
  353.   (ans->TABLE).comparator = comp;
  354.   (ans->TABLE).lisp_comparator = nil;
  355.   (ans->TABLE).tree = nil;
  356.  
  357.   return ans;
  358. }
  359.  
  360. LispObject allocate_module_function(LispObject *stacktop,
  361.                     LispObject mod,LispObject name,
  362.                     LispObject (*fun)(LispObject*),
  363.                     int code)
  364. {
  365.   LispObject ans;
  366.  
  367.   STACK_TMP(name); STACK_TMP(mod);
  368.   ans=allocate_nbytes(stacktop,sizeof(struct c_function_structure),TYPE_C_FUNCTION);
  369.   UNSTACK_TMP(mod); UNSTACK_TMP(name);
  370.   lval_classof(ans) = Function;
  371.  
  372.   ans->C_FUNCTION.name = name;
  373.   ans->C_FUNCTION.home = mod;
  374.   ans->C_FUNCTION.argtype = code;
  375.   ans->C_FUNCTION.env = NULL;
  376.  
  377.   ans->C_FUNCTION.func = fun;
  378.   
  379.   return ans;
  380. }
  381.  
  382. #ifdef NOLOWTAGINTS
  383. LispObject real_allocate_integer(LispObject *stacktop, int n)
  384. {
  385.   LispObject ans;
  386.  
  387.   if (n>=0 && n<STATIC_INTEGERS)
  388.     return vref(static_ints,n);
  389.  
  390.   ans=allocate_nbytes(stacktop,sizeof(struct integer_structure),TYPE_INT);
  391.  
  392.   lval_classof(ans)=Integer;
  393.   intval(ans)=n;
  394.  
  395.   return ans;
  396. }
  397. #endif
  398.  
  399. /* stubs to keep arith.c happy */
  400. LispObject allocate_ratio(LispObject *stacktop,LispObject m,LispObject n)
  401. {
  402.   NOT_YET_DONE("ratio");
  403. }
  404.  
  405. LispObject allocate_complex(LispObject *stacktop,LispObject m,LispObject n)
  406. {
  407.   NOT_YET_DONE("complex");
  408. }
  409.  
  410. LispObject allocate_float(LispObject *stacktop,double x)
  411. {
  412.   LispObject ans;
  413.  
  414.   ans=allocate_nbytes(stacktop,sizeof(struct float_structure),TYPE_FLOAT);
  415.  
  416.   lval_classof(ans)=Real;
  417.   ans->FLOAT.fvalue=x;
  418.   
  419.   return ans;
  420.   
  421. }
  422.  
  423. LispObject allocate_char(LispObject *stacktop, char x)
  424. {
  425.   LispObject ans;
  426.  
  427.   ans=allocate_nbytes(stacktop,sizeof(struct character_structure),
  428.               TYPE_CHAR);
  429.   lval_classof(ans)=Character;
  430.   ans->CHAR.font=0;
  431.   ans->CHAR.code=x;
  432.   return ans;
  433.   
  434. }
  435.  
  436. LispObject allocate_continue(LispObject *stacktop)
  437. {
  438.  
  439.   LispObject ans;
  440.  
  441.   ans=allocate_nbytes(stacktop,sizeof(struct continue_structure),TYPE_CONTINUE);
  442.  
  443.   lval_classof(ans) = Continue;
  444.  
  445.   (ans->CONTINUE).thread = nil;
  446.  
  447.   (ans->CONTINUE).value = nil;
  448.   (ans->CONTINUE).target = nil;
  449.  
  450.   /*  (ans->CONTINUE).machine_state; */
  451.   (ans->CONTINUE).gc_stack_pointer = NULL;
  452.   (ans->CONTINUE).dynamic_env = NULL;
  453.   (ans->CONTINUE).last_continue = nil;
  454.   (ans->CONTINUE).handler_stack = nil;
  455.  
  456.   (ans->CONTINUE).dp = nil;
  457.  
  458.   (ans->CONTINUE).live = FALSE;
  459.   (ans->CONTINUE).unwind = FALSE;  
  460.   
  461.   return ans;
  462. }
  463.  
  464. LispObject allocate_stream(LispObject *stacktop, FILE *file, int mod)
  465. {
  466.   LispObject ans;
  467.  
  468.   ans = allocate_nbytes(stacktop,sizeof(struct stream_structure),TYPE_STREAM);
  469.  
  470.   lval_classof(ans) = Object;
  471.   (ans->STREAM).handle = file;
  472.   (ans->STREAM).name = nil; /* Wah? */
  473.   (ans->STREAM).mode = mod;
  474.   (ans->STREAM).curchar = 0;
  475.   return ans;
  476.  
  477. }
  478.  
  479. LispObject allocate_env(LispObject *stacktop, LispObject name, 
  480.             LispObject value, LispObject prev)
  481. {
  482.   LispObject ans;
  483.  
  484.   STACK_TMP(prev); STACK_TMP(name); STACK_TMP(value);
  485.   ans=allocate_nbytes(stacktop,sizeof(struct envobject),TYPE_ENV);
  486.   UNSTACK_TMP(value); UNSTACK_TMP(name); UNSTACK_TMP(prev);
  487.   lval_classof(ans) = nil; /* ? */
  488.  
  489.   ans->ENV.variable = name;
  490.   ans->ENV.value = value;
  491.   ans->ENV.next = &prev->ENV;
  492.   ans->ENV.mutable = lisptrue;
  493.  
  494.   return ans;
  495. }
  496.  
  497. LispObject allocate_envimut(LispObject *stacktop, LispObject name, LispObject value, LispObject prev)
  498. {
  499.   LispObject ans;
  500.   
  501.   ans=allocate_env(stacktop,name,value,prev);
  502.   
  503.   ans->ENV.mutable = nil;
  504.   return ans;
  505. }
  506.  
  507. LispObject allocate_special(LispObject *stacktop, 
  508.                 LispObject name, 
  509.                 LispObject (*fn)(LispObject *))
  510. {
  511.   LispObject ans;
  512.  
  513.   STACK_TMP(name);
  514.   ans=allocate_nbytes(stacktop,sizeof(struct special_structure),TYPE_SPECIAL);
  515.   UNSTACK_TMP(name);
  516.  
  517.   lval_classof(ans) = Object;
  518.  
  519.   ans->SPECIAL.name  = name;
  520.   ans->SPECIAL.env   = NULL;
  521.   ans->SPECIAL.func  = fn;
  522.  
  523.   return(ans);
  524.  
  525. }
  526.  
  527.  
  528. LispObject allocate_i_function(LispObject *stacktop, LispObject mod, 
  529.                    LispObject env, int argcode)
  530. {
  531.   LispObject ans;
  532.  
  533.   STACK_TMP(mod); STACK_TMP(env);
  534.   ans=allocate_nbytes(stacktop,sizeof(struct i_function_structure),TYPE_I_FUNCTION);
  535.  
  536.   UNSTACK_TMP(env); UNSTACK_TMP(mod);
  537.   lval_classof(ans)=Function;
  538.   ans->I_FUNCTION.name=nil;
  539.   ans->I_FUNCTION.home = mod;
  540.   ans->I_FUNCTION.env = &env->ENV;
  541.   ans->I_FUNCTION.argtype = argcode;
  542.   
  543.   ans->I_FUNCTION.bvl = nil;
  544.   ans->I_FUNCTION.body = nil;
  545.  
  546.   return ans;
  547. }
  548.  
  549.  
  550. LispObject allocate_i_module(LispObject *stacktop, LispObject name)
  551. {
  552.   LispObject ans;
  553.   LispObject tmp1,tmp2;
  554.   
  555.   STACK_TMP(name);
  556.   tmp1 = (LispObject) allocate_table(stacktop, Fn_eq);
  557.   STACK_TMP(tmp1);
  558.   tmp2 = (LispObject) allocate_table(stacktop, Fn_eq);    
  559.   STACK_TMP(tmp2);
  560.   ans=allocate_nbytes(stacktop,sizeof(struct i_module_structure), TYPE_I_MODULE);
  561.   UNSTACK_TMP(tmp2);
  562.   UNSTACK_TMP(tmp1);
  563.   UNSTACK_TMP(name);
  564.   lval_classof(ans)=Object;
  565.   ans->I_MODULE.name = name;
  566.   ans->I_MODULE.home = nil;
  567.   ans->I_MODULE.exported_names = nil;
  568.   ans->I_MODULE.bounce_flag = FALSE;
  569.   ans->I_MODULE.imported_modules = nil; /* HACK !!! GC */
  570.   ans->I_MODULE.bindings = tmp2;
  571.   
  572.   return ans;
  573. }
  574.  
  575. #if (defined(WITH_BSD_SOCKETS) || defined(WITH_SYSTEMV_SOCKETS))
  576.  
  577. LispObject allocate_listener(LispObject *stacktop)
  578. {
  579.   LispObject ans;
  580.  
  581.   ans=allocate_nbytes(stacktop,sizeof(struct listener_structure), TYPE_LISTENER);
  582.   lval_classof(ans)=nil; /* will be set later */
  583.   return ans;
  584. }
  585.  
  586.  
  587. LispObject allocate_socket(LispObject *stacktop)
  588. {
  589.   LispObject ans;
  590.   
  591.   ans=allocate_nbytes(stacktop,sizeof(struct socket_structure), TYPE_SOCKET);
  592.   lval_classof(ans)=nil; /* will be set later */
  593.   return ans;
  594. }
  595. #endif
  596.  
  597. LispObject allocate_semaphore(LispObject *stacktop)
  598. {
  599.   LispObject ans;
  600.   
  601.   ans=allocate_nbytes(stacktop,sizeof(struct semaphore_structure), TYPE_SEMAPHORE);
  602.  
  603.   lval_classof(ans)=Object; /* Ugh */
  604.   system_allocate_semaphore(&(ans->SEMAPHORE.semaphore));
  605.  
  606.   return ans;
  607. }
  608.  
  609. LispObject allocate_static_vector(LispObject *stacktop,int nslots)
  610. {
  611.   LispObject space;
  612.   int i;
  613.  
  614.   space=(LispObject) allocate_space(stacktop,sizeof(Object_t)+sizeof(int)+nslots*sizeof(LispObject));
  615.   
  616.   for (i=0; i<nslots; i++)
  617.     vref(space,i)=NULL;
  618.  
  619.   lval_typeof(space)=TYPE_VECTOR|STATIC_TYPE;
  620.   lval_classof(space)=Vector;
  621.   gcof(space)=current_space();
  622.   space->VECTOR.length=nslots;
  623.  
  624.   return(space);
  625. }
  626.  
  627. /* These are never called */
  628. void deallocate_page(LispObject *stacktop, char *addr, int n)
  629. {
  630.   
  631. }
  632.  
  633. LispObject show_free_heap(LispObject *stacktop)
  634. {
  635.  
  636. }
  637.  
  638. LispObject show_free_space(LispObject *stacktop)
  639. {
  640.  
  641. }
  642.  
  643. void promote_free_space(LispObject *stacktop)
  644. {
  645.  
  646. }
  647.  
  648.  
  649. void allocate_static_integers(LispObject *stacktop)
  650. {
  651. #ifdef NOLOWTAGINTS
  652.   int i;
  653.  
  654.   static_ints=allocate_vector(stacktop,STATIC_INTEGERS);
  655.   for (i=0; i<STATIC_INTEGERS; i++)
  656.     {        /* alloc a big integer, then 'fix' it */
  657.       LispObject xx=real_allocate_integer(stacktop,STATIC_INTEGERS);
  658.       intval(xx)=i;
  659.       vref(static_ints,i)=xx;
  660.     }
  661.  
  662.   add_root(&static_ints);
  663. #endif
  664. }
  665.  
  666.  
  667. typedef struct free_list_struct
  668. {
  669.   int size;
  670.   struct free_list_struct *next;
  671. } *FreeList;
  672.  
  673. static SYSTEM_GLOBAL(FreeList, stack_chain);
  674.  
  675. static int free_count;
  676. static int nfrags;
  677.  
  678. #ifdef CGC
  679. void initialise_stack_space(int stackspace)
  680. {
  681.   gc_init();
  682. }
  683. #else
  684. #undef SYSTEM_MAX_SHARED_SIZE
  685. #define SYSTEM_MAX_SHARED_SIZE 512*1024
  686.  
  687. void initialise_stack_space(int stackspace)
  688. {
  689.   char *space;
  690.   int allocated=0;
  691.   FreeList *chain_end;
  692.   
  693.   SYSTEM_INITIALISE_GLOBAL(FreeList,stack_chain,NULL);
  694.  
  695.   chain_end=&SYSTEM_GLOBAL_VALUE(stack_chain);
  696.   nfrags=0;
  697.   while (allocated < stackspace)
  698.     {
  699.       space=system_malloc(SYSTEM_MAX_SHARED_SIZE);
  700.  
  701.       *chain_end=(FreeList)space;
  702.  
  703.       (*chain_end)->size= SYSTEM_MAX_SHARED_SIZE - sizeof(*chain_end);
  704.       (*chain_end)->next= NULL;
  705.       chain_end=&((*chain_end)->next);
  706.       free_count=SYSTEM_GLOBAL_VALUE(stack_chain)->size;
  707.       
  708.       allocated+=SYSTEM_MAX_SHARED_SIZE;
  709.       nfrags++;
  710.     }
  711. }
  712. #endif
  713.  
  714. void show_stack_space()
  715. {
  716.   fprintf(stderr,"Stack space: %d remaining, %d fragments\n",free_count, nfrags);
  717. }
  718.  
  719. /* use header as pointer to prevously allocated stack */
  720.  
  721. #ifdef CGC
  722. char* allocate_stack(LispObject *stacktop, int nbytes)
  723. {
  724.   return (char *)gc_malloc(nbytes);
  725. }
  726. #else
  727. char* allocate_stack(LispObject *stacktop, int nbytes)
  728. {
  729.   FreeList oldstack;
  730.   FreeList *walker;
  731.   char *ret;
  732.  
  733.   if (nbytes==0)
  734.     return NULL;
  735.  
  736.   system_open_semaphore(stacktop,&S_G_V(GC_sem)); 
  737.   walker= &SYSTEM_GLOBAL_VALUE(stack_chain);
  738.   nbytes=ROUND_ADDR(nbytes);
  739.  
  740.   free_count -= nbytes;
  741.  
  742.   while ( (*walker)!=NULL)
  743.     {
  744.       if ((*walker)->size+sizeof(*walker)==nbytes)
  745.     { 
  746.       ret= (char*) (*walker);
  747.       *walker=(*walker)->next;
  748.       nfrags--;
  749.       FPRINTF_GC_BUG((stderr,"{Cool stack: %x->%x}",ret,ret+nbytes));
  750.       GC_BUG(memset(ret,'S',nbytes));
  751.       system_close_semaphore(&S_G_V(GC_sem)); 
  752.       return ret;
  753.     }
  754.       if ((*walker)->size<nbytes)
  755.     {
  756.       FPRINTF_GC_BUG((stderr,"[Looking at: %x->%x (%d)]",*walker,(*walker)+(*walker)->size,
  757.               (*walker)->size));      
  758.       walker = &((*walker)->next);
  759.     }
  760.       else
  761.     {
  762.       ret= ((char *)((*walker)+1))+((*walker)->size-nbytes);
  763.       (*walker)->size=(*walker)->size-nbytes;
  764.       GC_BUG(memset(ret,'S',nbytes));
  765.       FPRINTF_GC_BUG((stderr,"{Alloc stack: %x->%x}",ret,ret+nbytes));
  766.       system_close_semaphore(&S_G_V(GC_sem)); 
  767.       return ret;
  768.     }
  769.     }
  770.   fprintf(stderr,"alloc stack: stack wimped out (%d remaining --- probably)\n",free_count);
  771.   system_close_semaphore(&S_G_V(GC_sem)); 
  772.   return NULL;
  773. }
  774. #endif
  775.  
  776. #ifdef CGC
  777. void deallocate_stack(LispObject *stacktop, char *addr,int nbytes)
  778. {
  779.  /* could use gc_free(object) here? */
  780. }
  781. #else
  782. void deallocate_stack(LispObject *stacktop, char *addr,int nbytes)
  783. {
  784.   FreeList old, walker;
  785.   /* Too damm lazy */
  786.   nbytes=ROUND_ADDR(nbytes);
  787.  
  788.   
  789.   system_open_semaphore(stacktop,&S_G_V(GC_sem)); 
  790.   walker=SYSTEM_GLOBAL_VALUE(stack_chain);
  791.   FPRINTF_GC_BUG((stderr,"{dealloc: %x->%x [%d]",addr,addr+nbytes,nbytes));
  792.   while (   ((char *)walker->next) < addr
  793.      && walker->next!=NULL)
  794.     {
  795.       /* sanity check */
  796. #if 0
  797.       if (walker >= walker->next)
  798.     { 
  799.       FPRINTF_GC_BUG((stderr,"Rats--- strange chain\n"));
  800.       system_lisp_exit(1);
  801.     }
  802. #endif
  803.       walker=walker->next;
  804.     }
  805.   /* 3 cases --- at the start */
  806.   if ( ((char *)(walker+1)) + walker->size == addr)
  807.     {
  808.       /* side check for end */
  809.  
  810.       if (walker->next!=NULL && addr+nbytes == (char *) walker->next)
  811.     {
  812.       walker->size = walker->size+nbytes
  813.         +sizeof(*walker)
  814.           +walker->next->size;
  815.       walker->next=walker->next->next;
  816.       free_count+=nbytes+sizeof(*walker);
  817.       nfrags--;
  818.       FPRINTF_GC_BUG((stderr,"Filler}"));
  819.     }
  820.       else    
  821.     {
  822.       walker->size=walker->size+nbytes;
  823.       free_count+=nbytes;
  824.       FPRINTF_GC_BUG((stderr,"Start}"));
  825.     }
  826.       system_close_semaphore(&S_G_V(GC_sem)); 
  827.       return;
  828.     }
  829.   /* at the end */
  830.   if ( walker->next!=NULL && addr+nbytes == (char *) walker->next)
  831.     {
  832.       old=walker->next;
  833.       walker->next=(FreeList) addr;
  834.       walker->next->size=nbytes+old->size;
  835.       walker->next->next=old->next;
  836.       free_count+=nbytes;
  837.       FPRINTF_GC_BUG((stderr,"End}"));
  838.       system_close_semaphore(&S_G_V(GC_sem)); 
  839.       return;
  840.     }
  841.   /* in the middle */
  842.   old=walker->next;      
  843.   walker->next=(FreeList) addr;
  844.   walker->next->next=old;
  845.   walker->next->size=nbytes-sizeof(*walker);
  846.   nfrags++;
  847.   free_count+=nbytes-sizeof(*walker);
  848.   FPRINTF_GC_BUG((stderr,"Middle}"));
  849.   system_close_semaphore(&S_G_V(GC_sem)); 
  850. }
  851. #endif 
  852.   
  853. int dump_obj(unsigned int *x,int s)
  854. {
  855.   int i;
  856.   
  857.   if (s>200) s=16;
  858.  
  859.   for (i=0; i<s ; i+=4)
  860.     fprintf(stderr,"0x%x: %x %x %x %x\n",
  861.         x+i,
  862.         (int)*(x+i),(int)*(x+i+1),(int)*(x+i+2),(int)*(x+i+3));
  863.   return s;
  864. }
  865.   
  866.